#include <map>
#include "ExpressionParser.h"
#include "ExpressionLexer.h"
#include "..\Common\AssertHelper.h"

using namespace std;

namespace CExpression
{
	void ExpressionParser::Parse(const ExpressionString &str)
	{
		ExpressionLexer lexer;
		ParseContext context(lexer.ParseTokens(str));
		while(context.Tokens().size()>0&&context.CurrentTokenIndex()<context.Tokens().size()&&!context.ErrorOccured())
		{
			this->pFirstHandler->ParseToken(context);
			ParseContext::TokenCollectionSize index=context.CurrentTokenIndex();
			context.SetCurrentTokenIndex(++index);
		}
		if(!context.ErrorOccured())
		{
			this->ParseLastToken(context);
			if(!context.ErrorOccured())
			{
				if(context.OperandStack().size()>1)
				{
					this->errorOccured=true;
					this->errMsg=TEXT("Missing operator.");
				}
				else if(context.OperandStack().size()==0)
				{
					this->errorOccured=true;
					this->errMsg=TEXT("There isn't valide element in this expression.");
				}
				else
				{
					this->pRootNode=context.OperandStack().top();
					this->pVariables=context.Variables();
				}
			}
			else
			{
				this->errorOccured=true;
				this->errMsg=context.ErrorMsg();
			}
		}
		else
		{
			this->errorOccured=true;
			this->errMsg=context.ErrorMsg();
		}
	}

	void ExpressionParser::ParseLastToken(ParseContext &context)
	{
		while(context.OperatorStack().size()>0)
		{
			shared_ptr<ExpressionToken> ptr=context.OperatorStack().top();
			context.OperatorStack().pop();
			if(ptr->Token[ptr->Token.size()-1]==TEXT('('))
			{
				context.SetError();
				context.SetErrorMsg(TEXT("Missing right bracket."));
				break;
			}
			if(AssertHelper::CreateHandlerExists(ptr->Token,context,TEXT("Unknow operator.")))
			{
				map<ExpressionString,ParseContext::CreateNodeHandlerPtr>::iterator iter=ParseContext::createHandlerMap->find(ptr->Token);
				iter->second(context);
			}
		}
	}
}